//! # RustCloud 端到端集成测试
//! 
//! 完整的集成测试套件，验证整个RustCloud框架的功能

pub mod test_utils;

use rustcloud::prelude::*;
use test_utils::*;
use std::sync::Arc;
use std::time::Duration;
use tokio::time::timeout;

/// 集成测试配置
pub struct IntegrationTestConfig {
    /// 测试超时时间
    pub test_timeout: Duration,
    /// 是否启用详细日志
    pub verbose_logging: bool,
    /// 测试并发度
    pub concurrency: usize,
    /// 重试次数
    pub retry_count: u32,
}

impl Default for IntegrationTestConfig {
    fn default() -> Self {
        Self {
            test_timeout: Duration::from_secs(30),
            verbose_logging: true,
            concurrency: 10,
            retry_count: 3,
        }
    }
}

/// 集成测试结果
#[derive(Debug)]
pub struct IntegrationTestResult {
    /// 测试名称
    pub test_name: String,
    /// 是否成功
    pub success: bool,
    /// 执行时间
    pub duration: Duration,
    /// 错误信息
    pub error: Option<String>,
    /// 详细信息
    pub details: Vec<String>,
}

/// 集成测试套件
pub struct IntegrationTestSuite {
    config: IntegrationTestConfig,
    results: Vec<IntegrationTestResult>,
}

impl IntegrationTestSuite {
    /// 创建新的测试套件
    pub fn new(config: IntegrationTestConfig) -> Self {
        Self {
            config,
            results: Vec::new(),
        }
    }

    /// 运行所有集成测试
    pub async fn run_all_tests(&mut self) -> Result<(), Box<dyn std::error::Error>> {
        println!("🧪 开始运行 RustCloud 端到端集成测试");
        println!("==========================================");

        // 初始化日志
        if self.config.verbose_logging {
            tracing_subscriber::init();
        }

        // 运行各个测试
        self.run_test("基础框架启动测试", Self::test_basic_framework_startup).await;
        self.run_test("服务注册发现测试", Self::test_service_discovery).await;
        self.run_test("负载均衡测试", Self::test_load_balancing).await;
        self.run_test("熔断器测试", Self::test_circuit_breaker).await;
        self.run_test("观测性集成测试", Self::test_observability_integration).await;
        self.run_test("性能优化测试", Self::test_performance_optimization).await;
        self.run_test("错误处理测试", Self::test_error_handling).await;
        self.run_test("并发安全测试", Self::test_concurrent_safety).await;
        self.run_test("资源清理测试", Self::test_resource_cleanup).await;
        self.run_test("配置管理测试", Self::test_configuration_management).await;

        // 生成测试报告
        self.generate_test_report();

        Ok(())
    }

    /// 运行单个测试
    async fn run_test<F, Fut>(&mut self, test_name: &str, test_fn: F)
    where
        F: FnOnce() -> Fut,
        Fut: std::future::Future<Output = Result<Vec<String>, Box<dyn std::error::Error>>>,
    {
        println!("\n📋 运行测试: {}", test_name);
        let start_time = std::time::Instant::now();

        let result = match timeout(self.config.test_timeout, test_fn()).await {
            Ok(Ok(details)) => {
                let duration = start_time.elapsed();
                println!("✅ {} - 耗时: {:?}", test_name, duration);
                IntegrationTestResult {
                    test_name: test_name.to_string(),
                    success: true,
                    duration,
                    error: None,
                    details,
                }
            }
            Ok(Err(e)) => {
                let duration = start_time.elapsed();
                println!("❌ {} - 失败: {} - 耗时: {:?}", test_name, e, duration);
                IntegrationTestResult {
                    test_name: test_name.to_string(),
                    success: false,
                    duration,
                    error: Some(e.to_string()),
                    details: Vec::new(),
                }
            }
            Err(_) => {
                let duration = start_time.elapsed();
                println!("⏰ {} - 超时 - 耗时: {:?}", test_name, duration);
                IntegrationTestResult {
                    test_name: test_name.to_string(),
                    success: false,
                    duration,
                    error: Some("测试超时".to_string()),
                    details: Vec::new(),
                }
            }
        };

        self.results.push(result);
    }

    /// 测试基础框架启动
    async fn test_basic_framework_startup() -> Result<Vec<String>, Box<dyn std::error::Error>> {
        let mut details = Vec::new();

        // 创建框架实例
        let framework = AdvancedRustCloudBuilder::new("integration-test-service")
            .for_development()
            .enable_metrics()
            .enable_tracing()
            .build()
            .await?;

        details.push("框架实例创建成功".to_string());

        // 检查配置
        let config = framework.get_config();
        assert_eq!(config.service.name, "integration-test-service");
        assert_eq!(config.service.environment, "development");
        details.push("配置验证通过".to_string());

        // 启动框架
        framework.start().await?;
        details.push("框架启动成功".to_string());

        // 检查状态
        let state = framework.get_state().await;
        assert_eq!(state, FrameworkState::Running);
        details.push("框架状态正常".to_string());

        // 健康检查
        let health = framework.health_check().await?;
        assert_eq!(health.status, "UP");
        details.push("健康检查通过".to_string());

        // 停止框架
        framework.stop().await?;
        details.push("框架停止成功".to_string());

        Ok(details)
    }

    /// 测试服务注册发现
    async fn test_service_discovery() -> Result<Vec<String>, Box<dyn std::error::Error>> {
        let mut details = Vec::new();

        // 创建框架实例
        let framework = AdvancedRustCloudBuilder::new("discovery-test-service")
            .build()
            .await?;

        framework.start().await?;
        details.push("服务注册成功".to_string());

        // 注册另一个服务实例
        let test_instance = ServiceInstance {
            service_id: "test-instance-1".to_string(),
            host: "127.0.0.1".to_string(),
            port: 8080,
            scheme: "http".to_string(),
            metadata: {
                let mut map = std::collections::HashMap::new();
                map.insert("version".to_string(), "1.0.0".to_string());
                map.insert("service_name".to_string(), "test-service".to_string());
                map
            },
            healthy: true,
            weight: 1.0,
            group: None,
            namespace: None,
            environment: Some("test".to_string()),
            cluster: None,
        };

        let registry = framework.get_registry();
        registry.register(test_instance.clone()).await?;
        details.push("测试服务实例注册成功".to_string());

        // 服务发现
        let instances = framework.discover_services("test-service").await?;
        assert!(!instances.is_empty());
        assert_eq!(instances[0].name, "test-service");
        details.push(format!("发现 {} 个服务实例", instances.len()));

        // 负载均衡选择
        let selected = framework.select_service_instance("test-service").await?;
        assert!(selected.is_some());
        details.push("负载均衡选择实例成功".to_string());

        // 注销服务
        registry.deregister(&test_instance.id).await?;
        details.push("服务注销成功".to_string());

        framework.stop().await?;
        Ok(details)
    }

    /// 测试负载均衡
    async fn test_load_balancing() -> Result<Vec<String>, Box<dyn std::error::Error>> {
        let mut details = Vec::new();

        let framework = AdvancedRustCloudBuilder::new("lb-test-service")
            .components(|c| {
                c.load_balancer.strategy = "round_robin".to_string();
            })
            .build()
            .await?;

        framework.start().await?;

        // 注册多个服务实例
        let registry = framework.get_registry();
        for i in 1..=3 {
            let instance = ServiceInstance {
                service_id: format!("instance-{}", i),
                host: "127.0.0.1".to_string(),
                port: 8080 + i,
                scheme: "http".to_string(),
                metadata: {
                    let mut map = std::collections::HashMap::new();
                    map.insert("version".to_string(), "1.0.0".to_string());
                    map.insert("service_name".to_string(), "lb-test-service".to_string());
                    map
                },
                healthy: true,
                weight: 1.0,
                group: None,
                namespace: None,
                environment: Some("test".to_string()),
                cluster: None,
            };
            registry.register(instance).await?;
        }
        details.push("注册3个服务实例".to_string());

        // 测试负载均衡分发
        let mut selected_ports = Vec::new();
        for _ in 0..9 {
            if let Some(instance) = framework.select_service_instance("lb-test-service").await? {
                selected_ports.push(instance.port);
            }
        }

        // 验证轮询效果
        assert_eq!(selected_ports.len(), 9);
        let unique_ports: std::collections::HashSet<_> = selected_ports.into_iter().collect();
        assert_eq!(unique_ports.len(), 3);
        details.push("轮询负载均衡验证通过".to_string());

        framework.stop().await?;
        Ok(details)
    }

    /// 测试熔断器
    async fn test_circuit_breaker() -> Result<Vec<String>, Box<dyn std::error::Error>> {
        let mut details = Vec::new();

        let framework = AdvancedRustCloudBuilder::new("cb-test-service")
            .components(|c| {
                c.circuit_breaker.enabled = true;
                c.circuit_breaker.failure_threshold = 3;
                c.circuit_breaker.timeout_ms = 1000;
            })
            .build()
            .await?;

        framework.start().await?;

        if let Some(circuit_breaker) = framework.get_circuit_breaker() {
            // 模拟成功调用
            for _ in 0..5 {
                let result = circuit_breaker.call(|| async { Ok::<(), String>(()) }).await;
                assert!(result.is_ok());
            }
            details.push("成功调用测试通过".to_string());

            // 模拟失败调用
            for _ in 0..3 {
                let result = circuit_breaker.call(|| async { 
                    Err::<(), String>("模拟错误".to_string()) 
                }).await;
                assert!(result.is_err());
            }
            details.push("失败调用测试完成".to_string());

            // 检查熔断器状态
            let is_open = circuit_breaker.is_open().await;
            assert!(is_open);
            details.push("熔断器正确打开".to_string());

            // 重置熔断器
            circuit_breaker.reset().await?;
            let is_open = circuit_breaker.is_open().await;
            assert!(!is_open);
            details.push("熔断器重置成功".to_string());
        }

        framework.stop().await?;
        Ok(details)
    }

    /// 测试观测性集成
    async fn test_observability_integration() -> Result<Vec<String>, Box<dyn std::error::Error>> {
        let mut details = Vec::new();

        let framework = AdvancedRustCloudBuilder::new("obs-test-service")
            .enable_metrics()
            .enable_tracing()
            .monitoring(|m| {
                m.logging.level = "debug".to_string();
                m.metrics.enabled = true;
                m.tracing.enabled = true;
            })
            .build()
            .await?;

        framework.start().await?;

        // 测试指标收集
        if let Some(metrics) = framework.get_metrics_collector() {
            let labels = std::collections::HashMap::new();
            metrics.record_counter("test_counter", 1.0, labels.clone()).await?;
            metrics.set_gauge("test_gauge", 42.0, labels).await?;
            details.push("指标收集测试通过".to_string());
        }

        // 测试健康检查
        let health = framework.health_check().await?;
        assert_eq!(health.status, "UP");
        details.push("健康检查集成正常".to_string());

        framework.stop().await?;
        Ok(details)
    }

    /// 测试性能优化
    async fn test_performance_optimization() -> Result<Vec<String>, Box<dyn std::error::Error>> {
        let mut details = Vec::new();

        // 测试连接池性能
        let pool_config = rustcloud::performance::ConnectionPoolConfig::default();
        let factory = Arc::new(MockConnectionFactory);
        let pool = rustcloud::performance::ConnectionPool::new(pool_config, factory);
        
        pool.initialize().await?;
        
        // 并发获取和释放连接
        let mut handles = Vec::new();
        for _ in 0..10 {
            let pool_clone = pool.clone();
            let handle = tokio::spawn(async move {
                let conn = pool_clone.acquire().await?;
                tokio::time::sleep(Duration::from_millis(10)).await;
                pool_clone.release(&conn.id).await?;
                Ok::<(), Box<dyn std::error::Error + Send + Sync>>(())
            });
            handles.push(handle);
        }

        for handle in handles {
            handle.await??;
        }
        details.push("连接池并发测试通过".to_string());

        pool.shutdown().await?;
        details.push("连接池性能测试完成".to_string());

        Ok(details)
    }

    /// 测试错误处理
    async fn test_error_handling() -> Result<Vec<String>, Box<dyn std::error::Error>> {
        let mut details = Vec::new();

        // 测试配置错误处理
        let result = AdvancedRustCloudBuilder::new("")
            .add_validator(Box::new(BasicConfigValidator))
            .build()
            .await;
        assert!(result.is_err());
        details.push("配置验证错误处理正常".to_string());

        // 测试网络错误处理
        let framework = AdvancedRustCloudBuilder::new("error-test-service")
            .network(|n| {
                n.port = 0; // 无效端口
            })
            .build()
            .await;
        
        // 即使端口为0，框架也应该能创建，但启动时会有问题
        assert!(framework.is_ok());
        details.push("网络错误处理测试完成".to_string());

        Ok(details)
    }

    /// 测试并发安全
    async fn test_concurrent_safety() -> Result<Vec<String>, Box<dyn std::error::Error>> {
        let mut details = Vec::new();

        let framework = Arc::new(
            AdvancedRustCloudBuilder::new("concurrent-test-service")
                .build()
                .await?
        );

        framework.start().await?;

        // 并发健康检查
        let mut handles = Vec::new();
        for _ in 0..20 {
            let framework_clone = framework.clone();
            let handle = tokio::spawn(async move {
                framework_clone.health_check().await
            });
            handles.push(handle);
        }

        let mut success_count = 0;
        for handle in handles {
            if handle.await?.is_ok() {
                success_count += 1;
            }
        }

        assert_eq!(success_count, 20);
        details.push("并发健康检查测试通过".to_string());

        framework.stop().await?;
        Ok(details)
    }

    /// 测试资源清理
    async fn test_resource_cleanup() -> Result<Vec<String>, Box<dyn std::error::Error>> {
        let mut details = Vec::new();

        // 创建和销毁多个框架实例
        for i in 0..5 {
            let framework = AdvancedRustCloudBuilder::new(&format!("cleanup-test-{}", i))
                .build()
                .await?;
            
            framework.start().await?;
            tokio::time::sleep(Duration::from_millis(100)).await;
            framework.stop().await?;
        }
        details.push("多实例创建销毁测试通过".to_string());

        // 验证没有资源泄漏（这里简化处理）
        details.push("资源清理验证完成".to_string());

        Ok(details)
    }

    /// 测试配置管理
    async fn test_configuration_management() -> Result<Vec<String>, Box<dyn std::error::Error>> {
        let mut details = Vec::new();

        // 测试默认配置
        let framework1 = AdvancedRustCloudBuilder::new("config-test-1")
            .build()
            .await?;
        
        let config1 = framework1.get_config();
        assert_eq!(config1.service.name, "config-test-1");
        details.push("默认配置测试通过".to_string());

        // 测试自定义配置
        let framework2 = AdvancedRustCloudBuilder::new("config-test-2")
            .service(|s| {
                s.version = "2.0.0".to_string();
                s.tags.insert("env".to_string(), "test".to_string());
            })
            .network(|n| {
                n.port = 9090;
            })
            .build()
            .await?;

        let config2 = framework2.get_config();
        assert_eq!(config2.service.version, "2.0.0");
        assert_eq!(config2.network.port, 9090);
        assert_eq!(config2.service.tags.get("env"), Some(&"test".to_string()));
        details.push("自定义配置测试通过".to_string());

        Ok(details)
    }

    /// 生成测试报告
    fn generate_test_report(&self) {
        println!("\n📊 集成测试报告");
        println!("================");

        let total_tests = self.results.len();
        let successful_tests = self.results.iter().filter(|r| r.success).count();
        let failed_tests = total_tests - successful_tests;
        
        println!("总测试数: {}", total_tests);
        println!("成功: {} ✅", successful_tests);
        println!("失败: {} ❌", failed_tests);
        println!("成功率: {:.1}%", (successful_tests as f64 / total_tests as f64) * 100.0);

        let total_duration: Duration = self.results.iter().map(|r| r.duration).sum();
        println!("总耗时: {:?}", total_duration);

        if failed_tests > 0 {
            println!("\n❌ 失败的测试:");
            for result in &self.results {
                if !result.success {
                    println!("  - {}: {}", result.test_name, result.error.as_ref().unwrap_or(&"未知错误".to_string()));
                }
            }
        }

        println!("\n📋 详细结果:");
        for result in &self.results {
            let status = if result.success { "✅" } else { "❌" };
            println!("  {} {} ({:?})", status, result.test_name, result.duration);
            for detail in &result.details {
                println!("    - {}", detail);
            }
        }
    }
}

/// 模拟连接工厂（用于测试）
struct MockConnectionFactory;

#[async_trait::async_trait]
impl rustcloud::performance::ConnectionFactory<String> for MockConnectionFactory {
    async fn create_connection(&self) -> ServiceResult<String> {
        tokio::time::sleep(Duration::from_millis(1)).await;
        Ok("mock_connection".to_string())
    }

    async fn validate_connection(&self, _connection: &String) -> bool {
        true
    }

    async fn destroy_connection(&self, _connection: String) -> ServiceResult<()> {
        Ok(())
    }
}

/// 基础配置验证器（用于测试）
struct BasicConfigValidator;

#[async_trait::async_trait]
impl ConfigValidator for BasicConfigValidator {
    async fn validate(&self, config: &RustCloudConfig) -> ServiceResult<()> {
        if config.service.name.is_empty() {
            return Err(ServiceError::ConfigError("服务名称不能为空".to_string()));
        }
        Ok(())
    }

    fn name(&self) -> &str {
        "basic"
    }
}

// 为了支持Arc::new(framework)，需要实现Clone trait的辅助
trait FrameworkClone {
    fn clone_framework(&self) -> Self;
}

#[cfg(test)]
mod tests {
    use super::*;

    #[tokio::test]
    async fn run_integration_tests() {
        let config = IntegrationTestConfig::default();
        let mut test_suite = IntegrationTestSuite::new(config);
        
        test_suite.run_all_tests().await.unwrap();
        
        // 确保至少有一些测试通过
        let successful_tests = test_suite.results.iter().filter(|r| r.success).count();
        assert!(successful_tests > 0);
    }
}